package edu.usc.tweetool.logic;

import java.awt.image.BufferedImage;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;


import edu.usc.tweetool.hibernate.Follow;
import edu.usc.tweetool.hibernate.FollowDAO;
import edu.usc.tweetool.hibernate.FollowId;
import edu.usc.tweetool.hibernate.RegUserDAO;
import edu.usc.tweetool.hibernate.TweetsDAO;
import edu.usc.tweetool.hibernate.UserTheta;
import edu.usc.tweetool.hibernate.UserThetaDAO;
import edu.usc.tweetool.hibernate.Users;
import edu.usc.tweetool.hibernate.UsersDAO;
import edu.usc.tweetool.util.CalTool;
import edu.usc.tweetool.util.DemoChart;
import edu.usc.tweetool.util.ImageFileSystem;

public class ResultProcess {

	private UserThetaDAO utDAO;
	private TweetsDAO tweetsDAO;
	private RegUserDAO ruDAO;
	private FollowDAO followDAO;
	private UsersDAO userDAO;
	// public static final String[] topics = { "Art_Design" };

	public static final String[] topics = { "Art_Design", "Book", "Business",
			"Charity", "Entertainment", "Family", "Fashion", "Food_Drink",
			"Health", "Music", "News", "Science_Techology", "Sports" };

	public ResultProcess() {

	}

	public String getPage(String username, String path) {

		Users user = getUser(username);
		UserTheta uut = utDAO.findById(user.getUserId());
		if (user == null) {
			return "invalid user name.";
		}
		List<Follow> follows = followDAO
				.findByProperty("id.follower", username);
		// sList<Follow> follows = followDAO.findByExample(new Follow(new
		// FollowId(
		// user.getUserId(), null)));
		StringBuffer sb = new StringBuffer();
		sb.append("UserId: " + user.getUserId() + "<br/>");
		sb.append("UserName: " + user.getUserName() + "<br/>");
		sb.append("Followers Size: " + follows.size() + "<br/>");
		sb.append("Update Date: " + "<br/>");
		sb.append("<br/>");
		sb.append("<h3>User's Topic Vector</h3>");
		sb.append("<br/>");
		sb.append(getTableTag());
		sb.append(produceHead());
		sb.append(produceRow(uut));
		sb.append("</table>");
		sb.append("<br/>");

		DemoChart dc = new DemoChart();
		dc.setNames(topics);
		dc.setCounts(CalTool.getFloatList(uut));
		BufferedImage topicImage = dc.generateGraph();
		String tpath = ImageFileSystem.saveImage(topicImage, path, "topic");
		sb.append("<img src=\"/Tweetool/" + tpath + "\"/>");
		
		sb.append("<br/>");
		sb.append("<h3>User's Following Topic Vector</h3>");
		sb.append(getTableTag());
		sb.append(produceHead());
		List<UserTheta> coreUT = new ArrayList<UserTheta>();
		for (Follow f : follows) {
			Users ff = getUser(f.getId().getFollowing());
			if (ff != null) {
				UserTheta utt = utDAO.findById(ff.getUserId());
				coreUT.add(utt);
				sb.append(produceRow(utt));
			}

		}
		sb.append("</table>");
		sb.append("<br/>");
		sb.append("<br/>");
		sb.append("<h3>User's Core Topic Vector</h3>");
		sb.append("<br/>");
		sb.append(getTableTag());
		sb.append(produceHead());
		UserTheta reUT = CalTool.getSumUserTheta(utDAO.findById(user
				.getUserId()), coreUT);
		sb.append(produceRow(reUT));
		System.out.println("Core UT: " + coreUT.size());
		sb.append("</table>");
		sb.append("<br/>");
		sb.append("<h3>Recommand Twitter by Angle</h3>");
		sb.append("<br/>");
		sb.append(getTableTag());
		sb.append(produceHead());
		for (UserTheta uta : CalTool.getClosest(reUT, utDAO.findAll(), false,
				10)) {
			sb.append(produceRow(uta));
		}
		sb.append("</table>");
		sb.append("<br/>");
		sb.append("<h3>Recommand Twitter by Distance</h3>");
		sb.append("<br/>");
		sb.append(getTableTag());
		sb.append(produceHead());
		for (UserTheta uta : CalTool
				.getClosest(reUT, utDAO.findAll(), true, 10)) {
			sb.append(produceRow(uta));
		}
		sb.append("</table>");
		sb.append("<br/>");
		sb.append("<h3>Most Close Friend</h3>");
		sb.append("<br/>");
		sb.append(getTableTag());
		sb.append(produceHead());
		for (UserTheta uta : CalTool.getClosest(uut, coreUT, false, 5)) {
			sb.append(produceRow(uta));
		}
		sb.append("</table>");
		sb.append("<br/>");
		return sb.toString();
	}

	public String getTopicThetas() {
		StringBuffer sb = new StringBuffer();
		List<UserTheta> uts = utDAO.findAll();
		System.out.println("UserTheta: " + uts.size());

		for (int i = 0; i < topics.length; i++) {
			sb.append("<br/>");
			sb.append("<h2>" + topics[i] + "</h2>");
			sb.append(getTableTag());
			sb.append(produceHead());
			UserTheta[] uto = CalTool.getTops(uts, i);
			for (int j = 0; j < uto.length; j++) {
				sb.append(produceRow(uto[j]));
			}
			sb.append("</table>");
		}

		return sb.toString();
	}

	private String getTableTag() {
		return "<table width='1300' border='1' align='center' "
				+ "style='border-collapse:collapse;table-layout:fixed;"
				+ "word-break:break-all;'>";
	}

	private String produceHead() {
		StringBuffer sb = new StringBuffer();
		sb.append("<th width='200pt'>Twitter Name</th>");
		sb.append("<th width='100pt'>Art_Design</th>");
		sb.append("<th width='100pt'>Books</td>");
		sb.append("<th width='100pt'>Business</td>");
		sb.append("<th width='100pt'>Charity</td>");
		sb.append("<th width='100pt'>Entertainment</td>");
		sb.append("<th width='100pt'>Family</td>");
		sb.append("<th width='100pt'>Fashion</td>");
		sb.append("<th width='100pt'>Food_Drink</td>");
		sb.append("<th width='100pt'>Health</td>");
		sb.append("<th width='100pt'>Music</td>");
		sb.append("<th width='100pt'>News</td>");
		sb.append("<th width='100pt'>Scienc_Tech</td>");
		sb.append("<th width='100pt'>Sports</td>");
		return sb.toString();
	}

	private String produceRow(UserTheta ut) {
		StringBuffer sb = new StringBuffer();
		Users u = null;
		if (ut != null) {
			u = userDAO.findById(ut.getUserId());
		}
		DecimalFormat df = new DecimalFormat("#0.00%");

		if (u != null) {

			sb.append("<tr>");
			sb.append("<td>");
			sb
					.append("<a href=\"http://twitter.com/" + u.getUserName()
							+ "\">");
			sb.append(u.getUserName());
			sb.append("</a>");
			sb.append("</td>");
			sb.append("<td>" + df.format(ut.getArtDesign()) + "</td>");
			sb.append("<td>" + df.format(ut.getBooks()) + "</td>");
			sb.append("<td>" + df.format(ut.getBusiness()) + "</td>");
			sb.append("<td>" + df.format(ut.getCharity()) + "</td>");
			sb.append("<td>" + df.format(ut.getEntertainment()) + "</td>");
			sb.append("<td>" + df.format(ut.getFamily()) + "</td>");
			sb.append("<td>" + df.format(ut.getFashion()) + "</td>");
			sb.append("<td>" + df.format(ut.getFoodDrink()) + "</td>");
			sb.append("<td>" + df.format(ut.getHealth()) + "</td>");
			sb.append("<td>" + df.format(ut.getMusic()) + "</td>");
			sb.append("<td>" + df.format(ut.getNews()) + "</td>");
			sb.append("<td>" + df.format(ut.getScienTech()) + "</td>");
			sb.append("<td>" + df.format(ut.getSports()) + "</td>");
			sb.append("</tr>");
		} else {
			System.out.println("No User: " + ut.getUserId());
		}
		return sb.toString();
	}

	private Users getUser(String username) {
		List<Users> users = userDAO.findByUserName(username);
		if (username == null || username.equals("") || users.size() == 0) {
			return null;
		}
		return users.get(0);
	}

	public UserThetaDAO getUtDAO() {
		return utDAO;
	}

	public void setUtDAO(UserThetaDAO utDAO) {
		this.utDAO = utDAO;
	}

	public TweetsDAO getTweetsDAO() {
		return tweetsDAO;
	}

	public void setTweetsDAO(TweetsDAO tweetsDAO) {
		this.tweetsDAO = tweetsDAO;
	}

	public RegUserDAO getRuDAO() {
		return ruDAO;
	}

	public void setRuDAO(RegUserDAO ruDAO) {
		this.ruDAO = ruDAO;
	}

	public FollowDAO getFollowDAO() {
		return followDAO;
	}

	public void setFollowDAO(FollowDAO followDAO) {
		this.followDAO = followDAO;
	}

	public UsersDAO getUserDAO() {
		return userDAO;
	}

	public void setUserDAO(UsersDAO userDAO) {
		this.userDAO = userDAO;
	}
}
